package com.ecommerce.product.controller;

import com.ecommerce.common.Result;
import com.ecommerce.product.entity.Product;
import com.ecommerce.product.service.ProductService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;

/**
 * 商品控制器
 * 
 * @author ecommerce-team
 * @version 1.0.0
 */
@Api(tags = "商品管理")
@RestController
@RequestMapping("/product")
@Validated
public class ProductController {
    
    private static final Logger log = LoggerFactory.getLogger(ProductController.class);
    
    @Autowired
    private ProductService productService;
    
    /**
     * 根据ID查询商品详情
     */
    @ApiOperation(value = "查询商品详情", notes = "根据商品ID查询商品详细信息")
    @ApiImplicitParam(name = "id", value = "商品ID", required = true, dataType = "Long", paramType = "path")
    @GetMapping("/{id}")
    public Result<Product> getProductById(@PathVariable("id") @NotNull(message = "商品ID不能为空") @Min(value = 1, message = "商品ID必须大于0") Long id) {
        log.info("查询商品详情: id={}", id);
        
        Product product = productService.getProductById(id);
        
        log.info("查询商品详情成功: id={}, title={}", id, product.getTitle());
        return Result.success("查询成功", product);
    }
    
    /**
     * 分页查询商品列表
     */
    @ApiOperation(value = "查询商品列表", notes = "分页查询商品列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", value = "页码（从0开始）", dataType = "int", paramType = "query", defaultValue = "0"),
        @ApiImplicitParam(name = "size", value = "每页大小", dataType = "int", paramType = "query", defaultValue = "10"),
        @ApiImplicitParam(name = "sortType", value = "排序类型：sales-销量，price_asc-价格升序，price_desc-价格降序，time-时间", dataType = "String", paramType = "query")
    })
    @GetMapping("/list")
    public Result<Page<Product>> getProductList(
            @RequestParam(value = "page", defaultValue = "0") @Min(value = 0, message = "页码不能小于0") Integer page,
            @RequestParam(value = "size", defaultValue = "10") @Min(value = 1, message = "每页大小不能小于1") Integer size,
            @RequestParam(value = "sortType", required = false) String sortType) {
        
        log.info("查询商品列表: page={}, size={}, sortType={}", page, size, sortType);
        
        Pageable pageable = PageRequest.of(page, size);
        Page<Product> productPage = productService.getProductsBySort(sortType, pageable);
        
        log.info("查询商品列表成功: totalElements={}, totalPages={}", 
                productPage.getTotalElements(), productPage.getTotalPages());
        return Result.success("查询成功", productPage);
    }
    
    /**
     * 根据分类查询商品
     */
    @ApiOperation(value = "根据分类查询商品", notes = "根据分类ID分页查询商品")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "categoryId", value = "分类ID", required = true, dataType = "Long", paramType = "path"),
        @ApiImplicitParam(name = "page", value = "页码（从0开始）", dataType = "int", paramType = "query", defaultValue = "0"),
        @ApiImplicitParam(name = "size", value = "每页大小", dataType = "int", paramType = "query", defaultValue = "10")
    })
    @GetMapping("/category/{categoryId}")
    public Result<Page<Product>> getProductsByCategory(
            @PathVariable("categoryId") @NotNull(message = "分类ID不能为空") @Min(value = 1, message = "分类ID必须大于0") Long categoryId,
            @RequestParam(value = "page", defaultValue = "0") @Min(value = 0, message = "页码不能小于0") Integer page,
            @RequestParam(value = "size", defaultValue = "10") @Min(value = 1, message = "每页大小不能小于1") Integer size) {
        
        log.info("根据分类查询商品: categoryId={}, page={}, size={}", categoryId, page, size);
        
        Pageable pageable = PageRequest.of(page, size);
        Page<Product> productPage = productService.getProductsByCategory(categoryId, pageable);
        
        log.info("根据分类查询商品成功: categoryId={}, totalElements={}", categoryId, productPage.getTotalElements());
        return Result.success("查询成功", productPage);
    }
    
    /**
     * 根据品牌查询商品
     */
    @ApiOperation(value = "根据品牌查询商品", notes = "根据品牌ID分页查询商品")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "brandId", value = "品牌ID", required = true, dataType = "Long", paramType = "path"),
        @ApiImplicitParam(name = "page", value = "页码（从0开始）", dataType = "int", paramType = "query", defaultValue = "0"),
        @ApiImplicitParam(name = "size", value = "每页大小", dataType = "int", paramType = "query", defaultValue = "10")
    })
    @GetMapping("/brand/{brandId}")
    public Result<Page<Product>> getProductsByBrand(
            @PathVariable("brandId") @NotNull(message = "品牌ID不能为空") @Min(value = 1, message = "品牌ID必须大于0") Long brandId,
            @RequestParam(value = "page", defaultValue = "0") @Min(value = 0, message = "页码不能小于0") Integer page,
            @RequestParam(value = "size", defaultValue = "10") @Min(value = 1, message = "每页大小不能小于1") Integer size) {
        
        log.info("根据品牌查询商品: brandId={}, page={}, size={}", brandId, page, size);
        
        Pageable pageable = PageRequest.of(page, size);
        Page<Product> productPage = productService.getProductsByBrand(brandId, pageable);
        
        log.info("根据品牌查询商品成功: brandId={}, totalElements={}", brandId, productPage.getTotalElements());
        return Result.success("查询成功", productPage);
    }
    
    /**
     * 根据价格区间查询商品
     */
    @ApiOperation(value = "根据价格区间查询商品", notes = "根据价格区间分页查询商品")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "minPrice", value = "最低价格", required = true, dataType = "BigDecimal", paramType = "query"),
        @ApiImplicitParam(name = "maxPrice", value = "最高价格", required = true, dataType = "BigDecimal", paramType = "query"),
        @ApiImplicitParam(name = "page", value = "页码（从0开始）", dataType = "int", paramType = "query", defaultValue = "0"),
        @ApiImplicitParam(name = "size", value = "每页大小", dataType = "int", paramType = "query", defaultValue = "10")
    })
    @GetMapping("/price-range")
    public Result<Page<Product>> getProductsByPriceRange(
            @RequestParam("minPrice") @NotNull(message = "最低价格不能为空") BigDecimal minPrice,
            @RequestParam("maxPrice") @NotNull(message = "最高价格不能为空") BigDecimal maxPrice,
            @RequestParam(value = "page", defaultValue = "0") @Min(value = 0, message = "页码不能小于0") Integer page,
            @RequestParam(value = "size", defaultValue = "10") @Min(value = 1, message = "每页大小不能小于1") Integer size) {
        
        log.info("根据价格区间查询商品: minPrice={}, maxPrice={}, page={}, size={}", minPrice, maxPrice, page, size);
        
        Pageable pageable = PageRequest.of(page, size);
        Page<Product> productPage = productService.getProductsByPriceRange(minPrice, maxPrice, pageable);
        
        log.info("根据价格区间查询商品成功: totalElements={}", productPage.getTotalElements());
        return Result.success("查询成功", productPage);
    }
    
    /**
     * 搜索商品
     */
    @ApiOperation(value = "搜索商品", notes = "根据关键词搜索商品")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "keyword", value = "搜索关键词", required = true, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "page", value = "页码（从0开始）", dataType = "int", paramType = "query", defaultValue = "0"),
        @ApiImplicitParam(name = "size", value = "每页大小", dataType = "int", paramType = "query", defaultValue = "10")
    })
    @GetMapping("/search")
    public Result<Page<Product>> searchProducts(
            @RequestParam("keyword") @NotNull(message = "搜索关键词不能为空") String keyword,
            @RequestParam(value = "page", defaultValue = "0") @Min(value = 0, message = "页码不能小于0") Integer page,
            @RequestParam(value = "size", defaultValue = "10") @Min(value = 1, message = "每页大小不能小于1") Integer size) {
        
        log.info("搜索商品: keyword={}, page={}, size={}", keyword, page, size);
        
        Pageable pageable = PageRequest.of(page, size);
        Page<Product> productPage = productService.searchProducts(keyword, pageable);
        
        log.info("搜索商品成功: keyword={}, totalElements={}", keyword, productPage.getTotalElements());
        return Result.success("搜索成功", productPage);
    }
    
    /**
     * 获取推荐商品
     */
    @ApiOperation(value = "获取推荐商品", notes = "分页获取推荐商品列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", value = "页码（从0开始）", dataType = "int", paramType = "query", defaultValue = "0"),
        @ApiImplicitParam(name = "size", value = "每页大小", dataType = "int", paramType = "query", defaultValue = "10")
    })
    @GetMapping("/recommend")
    public Result<Page<Product>> getRecommendProducts(
            @RequestParam(value = "page", defaultValue = "0") @Min(value = 0, message = "页码不能小于0") Integer page,
            @RequestParam(value = "size", defaultValue = "10") @Min(value = 1, message = "每页大小不能小于1") Integer size) {
        
        log.info("获取推荐商品: page={}, size={}", page, size);
        
        Pageable pageable = PageRequest.of(page, size);
        Page<Product> productPage = productService.getRecommendProducts(pageable);
        
        log.info("获取推荐商品成功: totalElements={}", productPage.getTotalElements());
        return Result.success("查询成功", productPage);
    }
    
    /**
     * 获取热销商品
     */
    @ApiOperation(value = "获取热销商品", notes = "分页获取热销商品列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", value = "页码（从0开始）", dataType = "int", paramType = "query", defaultValue = "0"),
        @ApiImplicitParam(name = "size", value = "每页大小", dataType = "int", paramType = "query", defaultValue = "10")
    })
    @GetMapping("/hot")
    public Result<Page<Product>> getHotProducts(
            @RequestParam(value = "page", defaultValue = "0") @Min(value = 0, message = "页码不能小于0") Integer page,
            @RequestParam(value = "size", defaultValue = "10") @Min(value = 1, message = "每页大小不能小于1") Integer size) {
        
        log.info("获取热销商品: page={}, size={}", page, size);
        
        Pageable pageable = PageRequest.of(page, size);
        Page<Product> productPage = productService.getHotProducts(pageable);
        
        log.info("获取热销商品成功: totalElements={}", productPage.getTotalElements());
        return Result.success("查询成功", productPage);
    }
    
    /**
     * 获取新品商品
     */
    @ApiOperation(value = "获取新品商品", notes = "分页获取新品商品列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", value = "页码（从0开始）", dataType = "int", paramType = "query", defaultValue = "0"),
        @ApiImplicitParam(name = "size", value = "每页大小", dataType = "int", paramType = "query", defaultValue = "10")
    })
    @GetMapping("/new")
    public Result<Page<Product>> getNewProducts(
            @RequestParam(value = "page", defaultValue = "0") @Min(value = 0, message = "页码不能小于0") Integer page,
            @RequestParam(value = "size", defaultValue = "10") @Min(value = 1, message = "每页大小不能小于1") Integer size) {
        
        log.info("获取新品商品: page={}, size={}", page, size);
        
        Pageable pageable = PageRequest.of(page, size);
        Page<Product> productPage = productService.getNewProducts(pageable);
        
        log.info("获取新品商品成功: totalElements={}", productPage.getTotalElements());
        return Result.success("查询成功", productPage);
    }
    
    /**
     * 批量查询商品
     */
    @ApiOperation(value = "批量查询商品", notes = "根据商品ID列表批量查询商品")
    @ApiImplicitParam(name = "ids", value = "商品ID列表", required = true, dataType = "List<Long>", paramType = "body")
    @PostMapping("/batch")
    public Result<List<Product>> getProductsByIds(@RequestBody @NotNull(message = "商品ID列表不能为空") List<Long> ids) {
        log.info("批量查询商品: ids={}", ids);
        
        List<Product> products = productService.getProductsByIds(ids);
        
        log.info("批量查询商品成功: count={}", products.size());
        return Result.success("查询成功", products);
    }
    
    /**
     * 检查商品库存
     */
    @ApiOperation(value = "检查商品库存", notes = "检查指定商品是否有足够库存")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "productId", value = "商品ID", required = true, dataType = "Long", paramType = "path"),
        @ApiImplicitParam(name = "quantity", value = "需要的数量", required = true, dataType = "int", paramType = "query")
    })
    @GetMapping("/{productId}/stock/check")
    public Result<Boolean> checkStock(
            @PathVariable("productId") @NotNull(message = "商品ID不能为空") @Min(value = 1, message = "商品ID必须大于0") Long productId,
            @RequestParam("quantity") @NotNull(message = "数量不能为空") @Min(value = 1, message = "数量必须大于0") Integer quantity) {
        
        log.info("检查商品库存: productId={}, quantity={}", productId, quantity);
        
        boolean hasStock = productService.checkStock(productId, quantity);
        
        log.info("检查商品库存结果: productId={}, quantity={}, hasStock={}", productId, quantity, hasStock);
        return Result.success("检查完成", hasStock);
    }
    
    /**
     * 获取商品统计信息
     */
    @ApiOperation(value = "获取商品统计信息", notes = "获取商品总数等统计信息")
    @GetMapping("/statistics")
    public Result<Long> getProductStatistics() {
        log.info("获取商品统计信息");
        
        Long totalCount = productService.getProductCount();
        
        log.info("获取商品统计信息成功: totalCount={}", totalCount);
        return Result.success("查询成功", totalCount);
    }
}